﻿using HtmlAgilityPack;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MarkDownFileSplitter.Htm
{
    internal class HtmToMarkdownConverter
    {

        private WebView2 m_webView; // 将WebBrowser改为WebView2
        private string m_htmFileName;

        public HtmToMarkdownConverter(WebView2 webView, string htmFileName) // 构造函数参数改为WebView2
        {
            m_webView = webView;
            m_htmFileName = htmFileName;
        }

        /// <summary>
        /// 将当前HTML内容保存为Markdown文件
        /// </summary>
        public async Task SaveAsMarkdown()
        {
            try
            {
                string markdown = await ConvertToMarkdown();
                //直接保存到与htm同目录下
                string markdownFilePath = Path.ChangeExtension(m_htmFileName, ".md");
                var s1 = Regex.Replace(markdown, "\n", System.Environment.NewLine);
                var s2= Regex.Replace(s1, "&nbsp;", " ");
                File.WriteAllText(markdownFilePath, s2, Encoding.UTF8);
                MessageBox.Show($"文件已成功保存为: {markdownFilePath}", "保存成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存Markdown文件时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 将HTML内容转换为Markdown格式
        /// </summary>
        /// <returns>转换后的Markdown文本</returns>
        private async Task<string> ConvertToMarkdown() // 修改为同步方法
        {
            StringBuilder markdown = new StringBuilder();

            try
            {
                if (m_webView != null) // 检查WebView2是否已初始化
                {
                    // 获取HTML内容
                    string document = await m_webView.ExecuteScriptAsync("document.documentElement.outerHTML"); // 获取整个HTML文档内容
                    document = Regex.Unescape(document.Trim('\"')); // 处理转义字符
                    // 获取所有元素并按顺序转换为Markdown
                    ConvertElementToMarkdown(document, markdown);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"转换为Markdown时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return markdown.ToString();
        }

        /// <summary>
        /// 递归处理HTML元素并转换为Markdown
        /// </summary>
        private void ConvertElementToMarkdown(string html, StringBuilder markdown) // 修改参数为string类型
        {
            // 解析HTML字符串为DOM元素
            var document = new HtmlAgilityPack.HtmlDocument();
            document.LoadHtml(html);

            bool goChild = true;

            foreach (var child in document.DocumentNode.ChildNodes) // 遍历子节点
            {
                switch (child.Name.ToLower())
                {
                    case "h1":
                        markdown.AppendLine($"# {child.InnerText?.Trim()}");
                        break;
                    case "h2":
                        markdown.AppendLine($"## {child.InnerText?.Trim()}");
                        break;
                    case "h3":
                        markdown.AppendLine($"### {child.InnerText?.Trim()}");
                        break;
                    case "p":
                        var str = child.InnerText?.Trim();
                        markdown.AppendLine(str);
                        break;
                    case "img":
                        markdown.AppendLine(child.OuterHtml);
                        break;
                    case "ul":
                    case "ol":
                        ProcessLists(child, markdown);
                        break;
                    case "table":
                        ProcessTables(child, markdown);
                        goChild = false;
                        break;
                }
                // 只处理子元素，不再递归调用
                if (child.HasChildNodes&& goChild)
                {
                    ConvertElementToMarkdown(child.InnerHtml, markdown);
                }
            }
        }

        /// <summary>
        /// 处理HTML中的列表元素
        /// </summary>
        private void ProcessLists(HtmlNode listElement, StringBuilder markdown) // 修改参数为HtmlNode类型
        {
            var liElements = listElement.SelectNodes("li"); // 使用HtmlAgilityPack选择li元素
            foreach (var li in liElements)
            {
                if (listElement.Name.ToLower() == "ul")
                {
                    markdown.AppendLine($"- {li.InnerText.Trim()}");
                }
                else if (listElement.Name.ToLower() == "ol")
                {
                    int index = 1;
                    markdown.AppendLine($"{index++}. {li.InnerText.Trim()}");
                }
            }
            markdown.AppendLine(); // 添加空行
        }

        /// <summary>
        /// 处理HTML中的表格元素
        /// </summary>
        private void ProcessTables(HtmlNode table, StringBuilder markdown) // 修改参数为HtmlNode类型
        {
            var rows = table.Descendants("tr"); // 使用HtmlAgilityPack选择tr元素
            bool isFirstRow = true;
            foreach (var row in rows)
            {
                var cells = row.SelectNodes("td");
                if (cells == null || cells.Count == 0)
                {
                    cells = row.SelectNodes("th");
                }

                if (cells != null && cells.Count > 0)
                {
                    string[] cellTexts = new string[cells.Count];
                    for (int i = 0; i < cells.Count; i++)
                    {
                        cellTexts[i] = cells[i].InnerText.Trim();
                    }

                    markdown.Append("| " + string.Join(" | ", cellTexts) + " |"+"\n");

                    // 添加表头分隔行
                    if (isFirstRow)
                    {
                        markdown.Append("| " + string.Join(" | ", Enumerable.Repeat("---", cells.Count)) + " |" + "\n");
                        isFirstRow = false;
                    }
                }
            }

            markdown.AppendLine(); // 添加空行
        }
    }
}
